/*
 * LedDeviceRibbon.hpp
 *
 *  Created on: 08.11.2011
 *      Author: Andrei Isupov
 *     Project: Lightpack
 *
 *  Lightpack is very simple implementation of the backlight for a laptop
 *
 *  Copyright (c) 2011 Mike Shatohin, mikeshatohin [at] gmail.com
 *
 *  Lightpack is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  Lightpack is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#pragma once

#include "ILedDevice.hpp"
#include "StructRgb.hpp"
#include "abstractserial.h"

#include "../../CommonHeaders/RIBBON_ID.h"     /* For device VID, PID, vendor name and product name */
#include "hidapi.h" /* USB HID API */

#include "../../CommonHeaders/COMMANDS.h"   /* CMD defines */

#define WRITE_BUFFER_INDEX_REPORT_ID    0
#define WRITE_BUFFER_INDEX_COMMAND      1
#define WRITE_BUFFER_INDEX_DATA_START   2
#define PACKAGE_START_BYTE   0x02
#define PACKAGE_STOP_BYTE    0x00
#define PACKAGE_READ_BIT     0x80

/* Ribbon memory map */
#define RIBBON_MEMORY_OFFSET_VERSION             0        /* 4 bytes version info */
#define RIBBON_MEMORY_OFFSET_COLORS_SIZE         4        /* 4 bytes length of the digital tape size*/
#define RIBBON_MEMORY_OFFSET_ANALOG_COLOR        8        /* 3 bytes color of the analog tape (rgb) */
#define RIBBON_MEMORY_OFFSET_COLORS_SEGMENTS     11       /* 1500 bytes - 500 colors (rgb) of the digital tape */
#define RIBBON_MEMORY_OFFSET_TAPE_TYPE           1511     /* 1 byte tape type - not used yet */
#define RIBBON_MEMORY_OFFSET_COLORS_INTERNAL     1512     /* 4 bytes length of the digital tape size - internal non-volatile memory */
#define RIBBON_MEMORY_OFFSET_INITIAL_COLOR_SIZE  1516     /* 4 bytes the initial color of the digital light tape - internal non-volatile memory */

#define MAX_PACKAGE_SIZE                       58


class LedDeviceRibbon : public ILedDevice
{
    Q_OBJECT
public:
    LedDeviceRibbon(QObject * parent = 0);
    ~LedDeviceRibbon();

public slots:
    void open();
    void setColors(const QList<QRgb> & /*colors*/);
    void switchOffLeds();
    void setRefreshDelay(int /*value*/);
    void setColorDepth(int /*value*/);
    void setSmoothSlowdown(int /*value*/);
    void setGamma(double /*value*/);
    void setBrightness(int /*value*/);
    void setColorSequence(QString value);
    void requestFirmwareVersion();
    void updateDeviceSettings();

private:
    bool writeBufferToDevice();
    bool sendReadCommand(int address, int size);
    bool readDataFromDevice(int address, int size);
    bool tryToReopenDevice();
    bool readDataFromDeviceWithCheck(int address, int size);
    bool writeBufferToDeviceWithCheck();
    void resizeColorsBuffer(int buffSize);
    void closeDevice();
    bool sendCommandReadVersion();
    bool writeColorBufferSize(int address,int buffSize);

private slots:
    void restartPingDevice(bool isSuccess);
    void timerPingDeviceTimeout();

private:
    hid_device *m_hidDevice;

    unsigned char m_readBuffer[64];    /* 0-ReportID, 1..65-data */
    unsigned char m_writeBuffer[64];   /* 0-ReportID, 1..65-data */

    double m_gamma;
    int m_brightness;

    QList<QRgb> m_colorsSaved;
    QList<StructRgb> m_colorsBuffer;

    QTimer *m_timerPingDevice;

    static const int PingDeviceInterval;
    static const int MaximumLedsCount;
};
